<?php
/**
 * Document
 * @filesource
 */
/**
 * Namespace
 */
namespace framework\library;
/**
 * Dependencies
 */
use framework\Front;
use framework\library\Response;
use framework\library\interfaces\Document_Interface;
/**
 * Document Class
 *
 * Contains the data necessary to provide a basic document structure that includes
 * a DOCTYPE, HTML, HEAD and BODY tags
 * 
 * Provides methods for adding stylesheets, javascript files, etc. to the document.
 * 
 * Extends Response only to provide a convenience when writing controllers. These 
 * classes do not need to be coupled.
 * 
 * @author Randy Casburn <randy@plurious.com>
 * @copyright Copyright Plurious Software, all rights reserved
 * @license MIT
 * @license http://www.opensource.org/licenses/mit-license.html
 * @link http://plurious.com/framework/documentation/classes/Front.html
 * @version 2.1
 * 
 * @uses framework\Front
 * @uses framework\library\Response
 */
class Document extends Response implements Document_Interface {

    /** holds the page metadata */
    private $data = array();

    /**
     * Sets up default data
     */
    public function __construct() {
        $this->data['lang'] = 'en';
        $this->data['baseUrl'] = ROOT_URL;
        $this->data['title'] = ucfirst(DEFAULT_ROUTE);
        $this->data['description'] = ucfirst(DEFAULT_ROUTE) . ' Page';
        $this->data['keywords'] = ucfirst(DEFAULT_ROUTE) . ' Page';
        $this->data['icon'] = '';
        $this->data['links'] = array();
        $this->data['styles'] = array();
        $this->data['scripts'] = array();
        $this->data['inBodyScripts'] = array();
        $this->data['google_analytics'] = '';
    }

    /**
     * Sets the page title (for the title bar)
     * 
     * @param string $title 
     */
    public function setTitle($title) {
        $this->data['title'] = $title;
    }

    /**
     * Sets the description for the header meta tag
     * 
     * @param string $description 
     */
    public function setDescription($description) {
        $this->data['description'] = $description;
    }

    /**
     * Sets the keywords for the header meta tag
     * 
     * @param string $description 
     */
    public function setKeywords($keywords) {
        $this->data['keywords'] = $keywords;
    }

    /**
     * Sets the links for the header rel tag
     * 
     * @param string $description 
     */
    public function addLink($href, $rel) {
        $this->data['links'][md5($href)] = array(
            'href' => $href,
            'rel' => $rel
        );
    }

    /**
     * Sets stylesheet information to add to document as a rel stylesheet link
     * 
     * @param string $href
     * @param string $rel
     * @param string $media 
     */
    public function addStyle($href, $rel = 'stylesheet', $media = 'screen') {
        $this->data['styles'][md5($href)] = array(
            'href' => $href,
            'rel' => $rel,
            'media' => $media
        );
    }

    /**
     * Sets javascript inforamtion to add to document as a script tag src
     * 
     * @param string $script 
     */
    public function addScript($script) {
        $this->data['scripts'][md5($script)] = $script;
    }

    /**
     * Sets raw script text to inserted in document just prior to closing body tag
     * 
     * @param string $scriptText 
     */
    public function addInPageScript($scriptText) {
        $scriptText = addslashes($scriptText);
        $this->data['inBodyScripts'][md5(substr($scriptText, 0, 10))] = $scriptText;
    }

    /**
     * Sets the page content that will be placed between the body tags
     * 
     * This is the main page content
     * 
     * @param string $content 
     */
    public function setContent($content) {
        $this->data['content'] = $content;
    }

    public function getTitle() {
        return $this->data['title'];
    }

    public function getDescription() {
        return $this->data['description'];
    }

    public function getKeywords() {
        return $this->data['keywords'];
    }

    public function getLinks() {
        return $this->data['links'];
    }

    public function getStyles() {
        return $this->data['styles'];
    }

    public function getScripts() {
        return $this->data['scripts'];
    }

    public function getInPageScripts() {
        return $this->data['inBodyScripts'];
    }

    public function getContent() {
        return $this->data['content'];
    }

    /**
     * Document is rendered as final page construction task
     * 
     * Applies the page content to the document template.
     *
     * @uses document.tpl Mandatory template file located in the layout directory or default layout directory
     * @uses Front
     * @uses Registry
     * @uses Config
     * @param string $output 
     * @param string $type accepts: document[default], json, rss2.0, atom
     */
    public function renderFinal($output, $type = 'document') {
        $this->setContent($output);
        if (strtolower($type) == 'rss') {
            $type = 'rss2.0';
        }
        $this->registry = Front::getInstance();
        $this->config = $this->registry->get('config');
        $layout = $this->config->get('config_layout');
        $file = $this->config->get('context_dir') . 'template/base/' . $type . '.tpl';
        if (!is_file($file)) {
            throw new DocumentException("The document template (" . $type . ") cannot be found. It must be located in the base template folder.  There should always be one in the base template folder folder. At a minimum it must contain the DOCTYPE, HTML, HEAD, BODY tags and at least echo \$content");
        }
        extract($this->data);
        ob_start();
        require($file);
        $output = ob_get_contents();
        ob_clean();
        $this->output($output, $type);
    }

}

class DocumentException extends \Exception {

    public function __construct($e) {
        trigger_error($e);
    }

}

?>